package com.colbert.jknife.processor;

import com.colbert.jknife.handler.BaseAnnotationHandler;
import com.colbert.jknife.handler.BindViewAnnotationHandler;
import com.colbert.jknife.handler.OnClickAnnotationHandler;
import com.colbert.jknife.handler.OnLongClickAnnotationHandler;
import com.colbert.jknife.model.CodeSetManager;
import com.colbert.jknife.model.ICodeSetManager;
import com.colbert.jknife.writer.IJavaFileWriter;
import com.colbert.jknife.writer.JavaFileWriter;
import com.google.auto.service.AutoService;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import java.util.*;

@SupportedSourceVersion(SourceVersion.RELEASE_7)
@AutoService(Processor.class)
public class JKnifeProcessor extends AbstractProcessor {

    private List<BaseAnnotationHandler> mHandlers;

    private Set<String> mSupportAnnotationTypes;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        mHandlers = new ArrayList<>();
        mSupportAnnotationTypes = new LinkedHashSet<>();
        registerHandler(new BindViewAnnotationHandler());
        registerHandler(new OnClickAnnotationHandler());
        registerHandler(new OnLongClickAnnotationHandler());
    }

    public void registerHandler(BaseAnnotationHandler handler) {
        handler.attachProcessingEnvironment(processingEnv);
        mSupportAnnotationTypes.add(handler.getAnnotationType().getCanonicalName());
        mHandlers.add(handler);
    }

    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        try {
            ICodeSetManager codeSetManager = CodeSetManager.getInstance();
            for (BaseAnnotationHandler handler : mHandlers) {
                if (!handler.handleAnnotation(roundEnv, codeSetManager)) {
                    return false;
                }
            }
            IJavaFileWriter writer = new JavaFileWriter.Builder()
                    .filer(processingEnv.getFiler())
                    .elements(processingEnv.getElementUtils())
                    .messager(processingEnv.getMessager())
                    .build();
            writer.generate(codeSetManager);
            codeSetManager.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return mSupportAnnotationTypes;
    }
}
